package meatslope2.application;

import java.io.InputStream;

import javax.microedition.khronos.opengles.GL10;

import meatslope2.constants.SpriteConstants;
import meatslope2.gameengine.engine.EngineRenderer;
import meatslope2.gameengine.engine.IRendererListener;
import meatslope2.gameengine.input.InputSystem;
import meatslope2.gameengine.scene.Scene;
import meatslope2.gameengine.scene.TileWorld;
import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.KeyEvent;
import android.view.MotionEvent;

public class GameApplication extends Activity implements IRendererListener, IGameContext
{
	// ===========================================================
	// Members
	// ===========================================================
	private Game game;
	private InputSystem inputSystem;
	
	private EngineRenderer engineRenderer;
	private GLSurfaceView surfaceView;
	
	private Scene scene;

	// ===========================================================
	// Getters/Setters
	// ===========================================================
	
	public TileWorld getTileWorld() 
	{
		return this.scene.getTileWorld();
	}
	
	// ===========================================================
	// Methods for/from SuperClass/Interfaces
	// ===========================================================
    @Override
    public void onCreate(Bundle savedInstanceState) //TODO: think of more logical start-up
    {
        super.onCreate(savedInstanceState);
        
        //Create scene
        this.scene = Scene.Factory.generateSampleLevel1(this);
        
		//Create input system
        this.inputSystem = new InputSystem(this.scene.getPlayer());
        
        //Pass scene, input system, dimensions into new engine
		this.game = new Game(this.scene, this.inputSystem);
		setGameWindow();
		
		this.inputSystem.setGame(this.game);
		
		this.engineRenderer = new EngineRenderer(this, this.game);
		
		//Create surface to draw on, set it's renderer to the one we just created
		this.surfaceView = new GLSurfaceView(this);
		this.surfaceView.setRenderer(engineRenderer);
        
        this.setContentView(surfaceView);
    }
	
	private void setGameWindow() 
	{
    	DisplayMetrics displaymetrics = new DisplayMetrics();
    	getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
    	final int height = displaymetrics.heightPixels;
    	final int width = displaymetrics.widthPixels;
    	
    	this.game.setWindow(width, height);
	}

	/**
	 * It's important that these steps are performed in this particular order
	 * 1.  SystemRegistry is initialized
	 * 2.  Scene's bitmaps are loaded (since we finally have a reference to our GLPointer)
	 * 3.  Start game
	 */
	public synchronized void onSurfaceCreated(GL10 pGL) 
	{
		//initialize our system registry
		new SystemRegistry(this, this.game, pGL);

		//We can load bitmaps
		SpriteConstants.loadSprites(this, pGL);
	
		//Now start the update cycle
		this.game.start();
	}

	@Override
    public boolean onKeyDown(int keyCode, KeyEvent event) 
    {
    	return inputSystem.onKeyDown(keyCode, event);
    }
    
    @Override
    public boolean onTouchEvent(MotionEvent event) 
    {
        return inputSystem.onTouchEvent(event);
    }

	public InputStream openRawResource(int resourceId) 
	{
		return getResources().openRawResource(resourceId);
	}

	public void onSurfaceChanged() 
	{
		setGameWindow();	
	}
}
